package manage.modules.group.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import manage.commons.utils.Pager;
import manage.commons.utils.TableNameUtil;
import manage.modules.BaseService;
import manage.modules.dept.model.GroupOfDept;
import manage.modules.group.model.Group;
import manage.modules.group.model.WorkerOfGroup;
import manage.modules.group.service.GroupService;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.jdbc.core.simple.ParameterizedBeanPropertyRowMapper;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.jdbc.core.simple.ParameterizedSingleColumnRowMapper;

public class GroupServiceImpl implements GroupService {
	private static final String GROUP_TABLE_PRIMARY = "groupId";
	private static final String GROUP_CACHE_KEY = "allGroup";
	private BaseService baseService;

	@Override
	public List<GroupOfDept> listGroupOfDeptByDeptId(Long deptId) {
		return baseService.listByField("deptId", deptId, GroupOfDept.class);
	}

	@Override
	public List<GroupOfDept> listGroupOfDeptByGroupId(Long groupId) {
		return baseService.listByField(GROUP_TABLE_PRIMARY, groupId,
				GroupOfDept.class);
	}

	@Override
	public List<Long> listDeptIdByGroupId(Long groupId) {
		String sql = "select deptId from "
				+ TableNameUtil.getTableName(GroupOfDept.class)
				+ " where groupId = ?";
		return baseService.getJdbcOperations().query(sql,
				ParameterizedSingleColumnRowMapper.newInstance(Long.class),
				groupId);
	}

	@Override
	public List<Group> listGroupByDeptId(Long deptId) {
		List<GroupOfDept> gOfdList = listGroupOfDeptByDeptId(deptId);
		List<Group> groups = new ArrayList<Group>();
		for (GroupOfDept groupOfDept : gOfdList) {
			Long groupId = groupOfDept.getGroupId();
			Group group = select(groupId);
			groups.add(group);
		}
		return groups;
	}

	@Override
	public Group select(Long groupId) {
		return baseService.select(GROUP_TABLE_PRIMARY, groupId, getClazz());
	}

	@Override
	public int insert(Group group) {
		int count = baseService.insert(group);
		clearCacheByCount(count);
		return count;
	}

	@Override
	public int update(Group group) {
		int count = baseService.updateFields(GROUP_TABLE_PRIMARY,
				group.getGroupId(), group);
		clearCacheByCount(count);
		return count;
	}

	@Override
	public int delete(Long groupId) {
		int count = baseService
				.delete(GROUP_TABLE_PRIMARY, groupId, getClazz());
		WorkerOfGroup workerOfGroup = new WorkerOfGroup();
		workerOfGroup.setGroupId(groupId);
		delete(workerOfGroup);
		clearCacheByCount(count);
		return count;
	}

	@Override
	public List<Group> listAll() {
		List<Group> allGroup = (List<Group>) baseService.getListByCache(
				GROUP_TABLE_PRIMARY, getClazz());
		if (CollectionUtils.isEmpty(allGroup)) {
			allGroup = baseService.listAll(getClazz());
			if (CollectionUtils.isNotEmpty(allGroup)) {
				baseService.setCache(GROUP_TABLE_PRIMARY, allGroup);
			}
		}
		return allGroup;
	}

	@Override
	public boolean exists(Long groupId) {
		return baseService.exists(GROUP_TABLE_PRIMARY, groupId, getClazz());
	}

	@Override
	public boolean workerVested(Long groupId) {
		return baseService.exists(GROUP_TABLE_PRIMARY, groupId,
				WorkerOfGroup.class);
	}

	@Override
	public int insert(WorkerOfGroup workerOfGroup) {
		return baseService.insert(workerOfGroup);
	}

	@Override
	public void insertWorkerOfGroups(Long workerId, List<Long> groupIds) {
		if (!CollectionUtils.isEmpty(groupIds)) {
			for (Long groupId : groupIds) {
				WorkerOfGroup workerOfGroup = new WorkerOfGroup();
				workerOfGroup.setGroupId(groupId);
				workerOfGroup.setWorkerId(workerId);
				insert(workerOfGroup);
			}
		}
	}

	@Override
	public int delete(WorkerOfGroup workerOfGroup) {
		Map<String, Object> wOfGroup = baseService.comparePojo(null, workerOfGroup);
		return baseService.deleteByFields(wOfGroup, WorkerOfGroup.class);
	}

	@Override
	public void deleteWorkerOfGroups(Long workerId, List<Long> groupIds) {
		if (!CollectionUtils.isEmpty(groupIds)) {
			for (Long groupId : groupIds) {
				WorkerOfGroup workerOfGroup = new WorkerOfGroup();
				workerOfGroup.setGroupId(groupId);
				workerOfGroup.setWorkerId(workerId);
				delete(workerOfGroup);
			}
		}
	}

	@Override
	public Long getCountOfAll() {
		return baseService.countOfAll(getClazz());
	}

	@Override
	public void query(Group group, Pager<Group> pager) {
		StringBuilder querySql = new StringBuilder(1024);
		querySql.append("select * from "
				+ TableNameUtil.getTableName(getClazz()) + " where 1=1");
		if (group != null) {
			if (null != group.getGroupId()) {
				querySql.append(" and groupId =" + group.getGroupId());
			}
			if (null != group.getDisabled()) {
				querySql.append(" and disabled =" + group.getDisabled());
			}
			if (StringUtils.isNotBlank(group.getGroupName())) {
				querySql.append(" and groupName like '%" + group.getGroupName()
						+ "%'");
			}
		}
		pager.setRowCount(baseService.getJdbcOperations().queryForLong(
				baseService.getCountSql(querySql.toString())));
		querySql.append(" limit ?,?");
		ParameterizedRowMapper<Group> rowMapper = ParameterizedBeanPropertyRowMapper
				.newInstance(getClazz());
		pager.setList(baseService.getJdbcOperations().query(
				querySql.toString(), rowMapper, pager.getRowOffset(),
				pager.getPageSize()));
	}

	private void clearCacheByCount(int count) {
		if (count > 0) {
			baseService.clearCache(GROUP_CACHE_KEY);
		}
	}

	public Class<Group> getClazz() {
		return Group.class;
	}

	public void setBaseService(BaseService baseService) {
		this.baseService = baseService;
	}

}
